package com.imis.base.util;

import cn.hutool.core.io.FileUtil;
import com.imis.base.constant.CommonConstant;
import com.imis.base.constant.enums.CommonResponseEnum;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>
 * FileUtils<br>
 * 文件相关 工具类
 * </p>
 *
 * @author XinLau
 * @version 1.0
 * @since 2020年04月19日 10:08
 */
@Slf4j
public class FileUtils extends FileUtil {

    /**
     * 重入锁
     */
    static Lock LOCK = new ReentrantLock();

    /**
     * 递归获取文件信息
     *
     * @param dir -
     * @return files -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/8/8 11:34
     */
    private static void getFiles(final File dir, Vector<String> files) {
        File[] fileList = dir.listFiles();
        assert fileList != null;
        for (File file : fileList) {
            if (file.isDirectory()) {
                getFiles(file, files);
            } else {
                files.add(file.getAbsolutePath());
            }
        }
    }

    /**
     * 重命名文件
     *
     * @param file    -
     * @param newName - 可以是文件名，也可以是路径+文件名
     * @return null -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/8/8 11:49
     */
    private static Boolean renameFile(File file, String newName) {
        if (file.exists()) {
            String targetPath;
            if (newName.contains(CommonConstant.SLASH) || newName.contains(CommonConstant.BACK_SLASH + CommonConstant.BACK_SLASH)) {
                targetPath = newName;
            } else {
                targetPath = file.getParentFile().getAbsolutePath() + CommonConstant.SLASH + newName;
            }
            File targetFile = new File(targetPath);
            file.renameTo(targetFile);
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * 递归获取文件信息
     *
     * @param path -
     * @return files -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/8/8 11:34
     */
    public static void getFiles(final String path, Vector<String> files) {
        getFiles(new File(path), files);
    }

    /**
     * 重命名文件
     *
     * @param filePath -
     * @param newName  - 可以是文件名，也可以是路径+文件名
     * @return Boolean -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/8/8 11:49
     */
    public static Boolean renameFile(String filePath, String newName) {
        File file = new File(filePath);
        return renameFile(file, newName);
    }

    /**
     * 获取目录下的文件
     *
     * @param dir       - 目录
     * @param fileType  - 文件类型
     * @param recursive - 是否遍历子目录
     * @return List<File> -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/8/13 17:31
     */
    public static List<File> listFile(File dir, final String fileType, Boolean recursive) {
        CommonResponseEnum.ERROR_500.assertIsTrue(dir.exists(), "目录：" + dir + "不存在");
        CommonResponseEnum.ERROR_500.assertIsTrue(dir.isDirectory(), dir + "不是目录");
        FileFilter fileFilter;
        if (fileType == null || fileType.length() == 0) {
            fileFilter = pathname -> true;
        } else {
            fileFilter = pathname -> {
                if (pathname.isDirectory()) {
                    return true;
                }
                String name = pathname.getName().toLowerCase();
                String format = name.substring(name.lastIndexOf(CommonConstant.DOT) + 1);
                return fileType.contains(format);
            };
        }
        return listFile(dir, fileFilter, recursive);
    }

    /**
     * 获取目录下的文件
     *
     * @param dir        - 目录
     * @param fileFilter - 文件过滤器
     * @param recursive  - 是否遍历子目录
     * @return List<File> -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/8/13 17:31
     */
    public static List<File> listFile(File dir, FileFilter fileFilter, Boolean recursive) {
        List<File> list = new ArrayList<>();
        File[] files = dir.listFiles(fileFilter);
        if (files != null && files.length > 0) {
            for (File file : files) {
                // 如果是文件,添加文件到 List 中
                if (file.isFile() || (file.isDirectory() && !file.getName().startsWith(CommonConstant.DOT))) {
                    list.add(file);
                } else if (recursive) {
                    // 获取子目录中的文件,添加子目录中的经过过滤的所有文件添加到list
                    list.addAll(listFile(file, fileFilter, true));
                }
            }
        }
        return list;
    }

}
